#ifndef PARSER_HPP
#define PARSER_HPP

#include "token_sets.hpp"
#include "lexer.hpp"
#include "AST.hpp"

#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <memory>

class Parser
{
	public:
	static ASTNode::aptr parse( std::istream& );
	
	private:
	Parser( std::istream& );
	
	ASTNode::aptr parseIdentifierOrSpecialization();
	ASTNode::aptr parseType();
	ASTNode::aptr parseVariableDeclaration();
	ASTNode::aptr parseTemplateSpecialization( const std::string& );
	ASTNode::aptr parseCall( ASTNode::aptr );
	ASTNode::aptr parsePrimaryExpression();
	ASTNode::aptr parseExpression();
	ASTNode::aptr parseStatement();
	ASTNode::aptr parseIf();
	ASTNode::aptr parseWhile();
	ASTNode::aptr parseDoWhile();
	ASTNode::aptr parseCodeBlock();
	ASTNode::aptr parseFunction();
	ASTNode::aptr parseModule();
	
	void match( Tkn::Token );
	void consume();
	
	void reportError( const std::string& );
	
	void reportInvalidToken();
	void reportUnexpectedToken();
	void reportUnexpectedToken( Tkn::Token );
	void reportUnexpectedToken( const std::string& );
	
	TknSets tsets;
	Lexer lexer;
	Tkn::Token token;
};

#endif // PARSER_HPP
